#include <bits/stdc++.h>
// 2025/06/10
// tag:
// Author: Forever
using namespace std;
using int64 = int64_t;

const int N = 300001;
int n, m, ans = 1, f[N];
vector<int> edge[N];

void dfs(int u, int fa)
{
    // 叶子节点处理：当子节点只有父节点时（度为1），初始化路径长度为1
    if (edge[u].size() == 1 && edge[u][0] == fa) {
        f[u] = 1;
        return;
    }

    int m1 = 0, m2 = 0; // 记录子树中最长路径的前两名

    // 遍历所有子节点（DFS过程）
    for (int v : edge[u]) {
        if (v == fa)
            continue; // 跳过父节点
        dfs(v, u); // 递归处理子节点

        // 维护最大和次大路径值
        if (f[v] > m1)
            m2 = m1, m1 = f[v];
        else if (f[v] > m2)
            m2 = f[v];
    }

    // 当前节点的最长路径 = 最大子路径 + 当前节点的分支数（排除父节点）
    f[u] = m1 + edge[u].size() - 1;

    // 更新全局答案（两种情况）：
    if (m2 == 0) // 只有单个子树的情况
        ans = max(ans, m1 + 1);
    // 两个子树通过当前节点连接的情况（路径长度 = m1 + m2 + 当前节点分支数）
    ans = max(ans, m1 + m2 + (int)edge[u].size() - 1);
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}